package com.example.smartcs.service.impl;

import com.example.smartcs.model.ChatMessage;
import com.example.smartcs.model.ChatRequest;
import com.example.smartcs.model.ChatResponse;
import com.example.smartcs.service.CustomerServiceAgent;
import com.example.smartcs.service.SessionService;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentSplitter;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.retriever.Retriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 高级客服代理实现类
 * 实现了基于大语言模型的智能客服系统，支持知识库检索和会话管理
 */
@Slf4j
@Service
@Primary
public class AdvancedCustomerServiceAgentImpl implements CustomerServiceAgent {

    // 注入必要的依赖
    private final ChatLanguageModel deepseekModel;  // DeepSeek模型
    private final ChatLanguageModel qwenModel;  // 通义千问模型
    private final EmbeddingStore<TextSegment> embeddingStore;  // 向量存储
    private final EmbeddingModel embeddingModel;  // 向量模型
    private final DocumentSplitter documentSplitter;  // 文档分割器
    private final MessageWindowChatMemory chatMemory;  // 聊天记忆
    private final SessionService sessionService;  // 会话服务
    
    // 知识库配置
    @Value("${knowledge.base.directory:knowledge}")
    private String knowledgeBaseDirectory;
    
    // 知识库检索相关
    private Retriever<TextSegment> retriever;
    private boolean knowledgeBaseInitialized = false;
    
    /**
     * 构造函数，注入所需的服务和模型
     */
    public AdvancedCustomerServiceAgentImpl(
            @Qualifier("deepseekModel") ChatLanguageModel deepseekModel,
            @Qualifier("qwenModel") ChatLanguageModel qwenModel,
            EmbeddingStore<TextSegment> embeddingStore,
            EmbeddingModel embeddingModel,
            DocumentSplitter documentSplitter,
            MessageWindowChatMemory chatMemory,
            SessionService sessionService) {
        this.deepseekModel = deepseekModel;
        this.qwenModel = qwenModel;
        this.embeddingStore = embeddingStore;
        this.embeddingModel = embeddingModel;
        this.documentSplitter = documentSplitter;
        this.chatMemory = chatMemory;
        this.sessionService = sessionService;
        
        // 确保knowledgeBaseDirectory有默认值
        if (this.knowledgeBaseDirectory == null || this.knowledgeBaseDirectory.trim().isEmpty()) {
            this.knowledgeBaseDirectory = "knowledge";
        }
        
        // 初始化知识库
        initKnowledgeBase();
    }
    
    /**
     * 初始化知识库
     * 1. 创建知识库目录
     * 2. 加载知识文件
     * 3. 初始化检索器
     */
    private void initKnowledgeBase() {
        try {
            // 检查嵌入模型是否可用
            if (embeddingModel == null) {
                log.warn("嵌入模型不可用，将不启用知识库检索功能");
                return;
            }
            
            // 创建知识库目录
            String projectRoot = System.getProperty("user.dir");
            if (projectRoot == null) {
                log.error("无法获取项目根目录");
                return;
            }
            
            File knowledgeDir = new File(projectRoot, knowledgeBaseDirectory);
            if (knowledgeDir == null) {
                log.error("知识库目录路径无效");
                return;
            }
            
            if (!knowledgeDir.exists()) {
                if (!knowledgeDir.mkdirs()) {
                    log.error("无法创建知识库目录: {}", knowledgeDir.getAbsolutePath());
                    return;
                }
                log.info("创建知识库目录: {}", knowledgeDir.getAbsolutePath());
                
                // 创建示例知识文件
                createSampleKnowledgeFile();
            }
            
            // 加载知识文件
            File[] files = knowledgeDir.listFiles();
            if (files == null) {
                log.error("无法读取知识库目录内容");
                return;
            }
            
            if (files.length > 0) {
                log.info("开始加载知识库文件，共{}个文件", files.length);
                
                EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                        .documentSplitter(documentSplitter)
                        .embeddingModel(embeddingModel)
                        .embeddingStore(embeddingStore)
                        .build();
                
                // 处理每个知识文件
                for (File file : files) {
                    if (file.isFile() && (file.getName().endsWith(".txt") || file.getName().endsWith(".md"))) {
                        try {
                            log.info("正在处理知识文件: {}", file.getName());
                            
                            // 读取文件内容
                            StringBuilder content = new StringBuilder();
                            try (BufferedReader reader = new BufferedReader(
                                    new InputStreamReader(
                                            new FileInputStream(file),
                                            java.nio.charset.StandardCharsets.UTF_8))) {
                                String line;
                                while ((line = reader.readLine()) != null) {
                                    content.append(line).append("\n");
                                }
                            }
                            
                            // 将内容添加到知识库
                            Document document = Document.from(content.toString());
                            ingestor.ingest(document);
                            log.info("成功将知识文件加入知识库: {}", file.getName());
                        } catch (Exception e) {
                            log.error("加载知识文件失败: " + file.getName(), e);
                        }
                    }
                }
                
                // 初始化检索器
                retriever = EmbeddingStoreRetriever.from(embeddingStore, embeddingModel, 3);
                knowledgeBaseInitialized = true;
                log.info("知识库初始化完成");
            } else {
                log.warn("知识库目录为空，将使用无知识库模式");
            }
        } catch (Exception e) {
            log.error("初始化知识库失败", e);
        }
    }
    
    /**
     * 创建示例知识文件
     * 包含一些基本的客服问答内容
     */
    private void createSampleKnowledgeFile() {
        try {
            String projectRoot = System.getProperty("user.dir");
            File knowledgeDir = new File(projectRoot, knowledgeBaseDirectory);
            File sampleFile = new File(knowledgeDir, "customer_service_faq.txt");
            
            if (!sampleFile.exists()) {
                if (!sampleFile.createNewFile()) {
                    log.error("无法创建示例知识文件: {}", sampleFile.getAbsolutePath());
                    return;
                }
                
                // 示例问答内容
                String sampleContent = "常见问题解答：\n\n" +
                        "1. 如何重置密码？\n" +
                        "您可以点击登录页面的\"忘记密码\"链接，然后按照提示步骤进行操作。系统会向您的注册邮箱发送重置密码的链接。\n\n" +
                        "2. 订单配送时间是多久？\n" +
                        "一般情况下，我们在收到订单后1-3个工作日内发货，具体到达时间取决于您的收货地址，一般为发货后1-5天。\n\n" +
                        "3. 如何申请退款？\n" +
                        "您可以在\"我的订单\"中找到需要退款的订单，点击\"申请退款\"按钮，并按照系统提示完成退款申请。审核通过后，款项将在7个工作日内退回您的支付账户。\n\n" +
                        "4. 产品质量问题如何处理？\n" +
                        "如果您收到的产品有质量问题，请在收货后48小时内联系客服，并提供产品问题的照片证明，我们会为您安排退换货或其他解决方案。\n\n" +
                        "5. 是否支持货到付款？\n" +
                        "目前我们在部分城市支持货到付款服务，您可以在下单时查看您的收货地址是否支持此服务。\n\n";
                
                // 写入文件
                try (BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(sampleFile),
                                java.nio.charset.StandardCharsets.UTF_8))) {
                    writer.write(sampleContent);
                }
                log.info("已创建示例知识库文件: {}", sampleFile.getAbsolutePath());
            }
        } catch (Exception e) {
            log.error("创建示例知识文件失败", e);
        }
    }

    /**
     * 处理用户请求
     * 1. 管理会话
     * 2. 检索相关知识
     * 3. 调用大模型生成回答
     * 4. 保存对话记录
     */
    @Override
    public ChatResponse processRequest(ChatRequest request) {
        // 获取或创建会话ID
        String sessionId = request.getSessionId();
        if (sessionId == null || sessionId.isEmpty()) {
            sessionId = sessionService.createNewSession();
        }

        // 记录用户消息
        ChatMessage userMessage = ChatMessage.builder()
                .id(UUID.randomUUID().toString())
                .sessionId(sessionId)
                .content(request.getMessage())
                .role("user")
                .timestamp(LocalDateTime.now())
                .build();
        sessionService.addMessageToSession(userMessage);
        
        // 获取会话历史
        List<ChatMessage> sessionMessages = sessionService.getSessionMessages(sessionId);
        StringBuilder history = new StringBuilder();
        for (ChatMessage msg : sessionMessages) {
            String role = "user".equals(msg.getRole()) ? "用户" : "助手";
            history.append(role).append(": ").append(msg.getContent()).append("\n");
        }
        
        // 构建系统提示词
        String systemPrompt = "你是一个专业、友好的客服代表。请基于以下对话历史、知识库信息和用户问题，提供清晰、准确和有帮助的回答。" +
                "如果你不确定答案，请诚实地说明你不知道而不是编造信息。" +
                "以友好、专业的口吻回答，并确保回答简洁明了。\n\n";
        
        // 检索相关知识
        List<TextSegment> relevantDocs = null;
        if (knowledgeBaseInitialized && retriever != null) {
            try {
                relevantDocs = retriever.findRelevant(request.getMessage());
                log.info("找到相关知识库内容: {}", relevantDocs.size());
            } catch (Exception e) {
                log.error("检索知识库时出错", e);
            }
        }
        
        // 构建完整提示词
        StringBuilder promptBuilder = new StringBuilder(systemPrompt);
        promptBuilder.append("对话历史:\n").append(history).append("\n\n");
        
        if (relevantDocs != null && !relevantDocs.isEmpty()) {
            promptBuilder.append("知识库相关信息:\n");
            for (TextSegment doc : relevantDocs) {
                promptBuilder.append(doc.text()).append("\n");
            }
            promptBuilder.append("\n");
        }
        
        promptBuilder.append("请回答用户的问题。");
        String prompt = promptBuilder.toString();
        
        // 选择模型并生成回答
        String modelType = request.getModelType();
        if (modelType == null || modelType.isEmpty()) {
            modelType = "deepseek"; // 默认使用DeepSeek
        }
        
        String response;
        try {
            // 根据选择的模型生成回答
            if ("qwen".equalsIgnoreCase(modelType)) {
                response = qwenModel.generate(prompt);
            } else {
                response = deepseekModel.generate(prompt);
            }
            
            // 记录AI回复
            String messageId = UUID.randomUUID().toString();
            ChatMessage aiMessage = ChatMessage.builder()
                    .id(messageId)
                    .sessionId(sessionId)
                    .content(response)
                    .role("assistant")
                    .modelType(modelType)
                    .timestamp(LocalDateTime.now())
                    .build();
            sessionService.addMessageToSession(aiMessage);
            
            // 返回响应
            return ChatResponse.builder()
                    .sessionId(sessionId)
                    .messageId(messageId)
                    .message(response)
                    .modelType(modelType)
                    .timestamp(LocalDateTime.now())
                    .build();
            
        } catch (Exception e) {
            log.error("请求大模型API失败", e);
            
            // 处理错误情况
            String errorMessage = "抱歉，服务暂时不可用，请稍后再试。";
            String messageId = UUID.randomUUID().toString();
            ChatMessage errorResponseMessage = ChatMessage.builder()
                    .id(messageId)
                    .sessionId(sessionId)
                    .content(errorMessage)
                    .role("assistant")
                    .modelType(modelType)
                    .timestamp(LocalDateTime.now())
                    .build();
            sessionService.addMessageToSession(errorResponseMessage);
            
            return ChatResponse.builder()
                    .sessionId(sessionId)
                    .messageId(messageId)
                    .message(errorMessage)
                    .modelType(modelType)
                    .timestamp(LocalDateTime.now())
                    .build();
        }
    }
} 